; tesselation related procs..
;============================================================
triangulize_all_faces:    ;; tesselate tris
; if eax = 'tiv' - teslate tris with at last one edge
; that intersect other tri and at last one inner vertex
; if ebx = 'chun' - tesllate separate chunk, and ecx = chunk id number
; to tesselate
;
; out:           esi - new triangles ptr
;                edi - new vertices ptr
;                ecx - new vertices count
;                ebx - new tris count
     .piv                       equ  [ebp-4]
     .index3                    equ  [ebp-8]
     .index2                    equ  [ebp-12]
     .index1                    equ  [ebp-16]
     .cnt1                      equ  [ebp-20]
     .mx                        equ  [ebp-146]
     .new_vcnt                  equ  dword[ebp-60]
     .new_vert_ptr              equ  [ebp-64]
     .new_tri                   equ  [ebp-68]
     .end_new_tri               equ  dword[ebp-72]
     .endt                      equ  [ebp-76]
     .endin                     equ  [ebp-80]
     .n_tri_cnt                 equ  dword[ebp-84]
     .piv2                      equ  dword[ebp-88]
     .tiv                       equ  dword[ebp-92]
     .ptr                       equ  dword[ebp-96]
     .tri_index                 equ  dword[ebp-100]
     .chu_no                    equ  dword[ebp-104]
     .chunkY                    equ  dword[ebp-108]
     .points_count_var          equ  dword[ebp-48]  ; !!
     .triangles_count_var       equ  dword[ebp-44]  ; covers .mx area
     .points_r_ptr              equ  dword[ebp-40]  ; !!
     .triangles_ptr             equ  dword[ebp-36]
     .points_rotated_ptr        equ  dword[ebp-32]
     .pnr                       equ  dword[ebp-28]
     .edges_ptr                 equ  dword[ebp-24]
     .edges_count               equ  dword[ebp-20]

     push     ebp
     mov      ebp,esp
     sub      esp,150
   ;  xor      eax,eax
   ;  call     do_edges_list_ch



     mov      .chunkY,ebx
     mov      .chu_no,ecx
     cld
     lea      esi,[points_count_var]
     lea      edi,.points_count_var
     mov      ecx,8
     rep      movsd
     xor      ebx,ebx
     mov      ecx,1
     cmp      eax,'tiv'
     cmovne   ecx,ebx
     mov      .tiv,ecx
     cmp      cl,1
     jne      .anonym
     cmp      [edges_intersect_ptr],ebx
     je       .end_aa
     cmp      [inner_vert_ptr],ebx
     je       .end_aa
   .anonym:
     mov      ebx,.edges_count
     shl      ebx,4
     add      ebx,60
     malloc   ebx
     mov      .piv,eax
     mov      eax,.points_count_var
     shl      eax,2
     add      eax,60
     cmp      eax,ebx
     cmova    ebx,eax

     malloc   ebx
     mov      .piv2,eax
     mov      .ptr,eax
     mov      eax,.edges_count
     add      eax,.points_count_var
     mov      .new_vcnt,eax      ; all vertices count
     add      eax,10
     shl      eax,2
     lea      eax,[eax*3]
     malloc   eax
     mov      .new_vert_ptr,eax  ; new vertices and old vertices

     mov      eax,.triangles_count_var
     lea      eax,[eax*3]
     shl      eax,4
     add      eax,60
     malloc   eax
     mov      .new_tri,eax
    ;make pivot table of edges
     mov      edi,.piv
     mov      esi,.edges_ptr
     xor      ecx,ecx
     xorps    xmm0,xmm0
   .anonym1:
     mov      eax,ecx
     movsd
     stosd
     movsd
     stosd
     inc       ecx
     cmp       ecx,.edges_count
     jne       .anonym1
     ;sort pivot table           - sort by qsort !!
     mov       esi,.piv
     mov       edi,.piv2
     mov       .endt,esi         ; calc end of  .piv
     mov       ecx,.edges_count
     add       ecx,ecx
     mov       eax,ecx
     shl       eax,3
     add       .endt,eax
     call      sort_hybrid       ; sort.inc
     ;make _ptr list
     mov    esi,.piv
     mov    edi,.ptr
   .bas:
     mov    ebx,esi   ; base
   .nob:              ; no base
     cmp    esi,.endt
     ja    .enn
     mov    eax,[esi]
     cmp    eax,[esi+8]
     je     .anonym2
     shl    eax,2
     add    eax,.ptr
     mov    [eax],ebx   ; ptr of vertices, each position point to edges pivot tab
     add    esi,8
     jne    .bas
     jmp    .enn
   .anonym2:
     add    esi,8
     cmp    esi,.endt
     jna    .nob

   .enn:
     mov      ecx,.points_count_var
     mov      esi,.points_r_ptr
     mov      edi,.new_vert_ptr ;eax
     mov      ebx,matrix_scaled
     cld
     call     rotary              ; for extra accurate
     cvtdq2ps xmm3,[xxadd]
     andps    xmm3,[zero_hgst_dd]
     mov      ecx,.points_count_var
     mov      ebx,.new_vert_ptr
   @@:
     movups   xmm1,[ebx]
     addps    xmm1,xmm3
     movups   [ebx],xmm1
     add      ebx,12
     loop     @b
     mov      edi,.points_count_var
     imul     edi,12
     add      edi,.new_vert_ptr
     mov      esi,.edges_ptr      ; calc all new vertices
     mov      ecx,.edges_count    ; every possible vert
     mov      eax,0.5             ; even if one chunk/selected fragment
                                  ; tesselation  ...
     movd     xmm0,eax            ; Proc need correct edges list to properly
     shufps   xmm0,xmm0,0         ; work
     cld
     mov     edx,.new_vert_ptr
   .calc_mid_vert:
     lodsd
     xchg     eax,ebx
     lodsd
     xchg     eax,ebx
     imul     eax,12
     imul     ebx,12
     add      eax,edx
     add      ebx,edx
     movups   xmm1,[eax]
     movups   xmm2,[ebx]
     addps    xmm2,xmm1
     mulps    xmm2,xmm0
     movups   [edi],xmm2
     add      edi,12
     loop     .calc_mid_vert
     mov      esi,.triangles_ptr
     mov      edi,.new_tri ;eax
     mov      ecx,.triangles_count_var
     lea      ecx,[ecx*3]
     push     ecx
     inc      ecx
     cld
     rep      movsd
     pop      ecx
     shl      ecx,2
     add      ecx,.new_tri  ;eax
     mov      .end_new_tri,ecx
     xor      esi,esi
     mov      .n_tri_cnt,esi
     mov      esi,.new_tri
     xor      ecx,ecx
   .chck:
     push     ecx
     mov      .tri_index,ecx
     push     esi
     cmp      [tes_mod_flag],1 ; test if check  - 'in teslate area'
     je       .in_area         ; no ?

     mov      eax,[esi]
     mov      ebx,[esi+4]
     mov      edx,[esi+8]
     imul     eax,12
     imul     ebx,12
     imul     edx,12
     add      eax,.new_vert_ptr
     add      ebx,.new_vert_ptr
     add      edx,.new_vert_ptr
     movlps   xmm0,[eax]
     movlps   xmm1,[ebx]
     movlps   xmm2,[edx]
     movlhps  xmm0,xmm0
     movlhps  xmm1,xmm1
     movlhps  xmm2,xmm2
     mov      eax,tri_area_x1
     cmpltps  xmm0,[eax]    ; check if whole tri in teslate area
     cmpltps  xmm1,[eax]
     cmpltps  xmm2,[eax]
     movhlps  xmm3,xmm0
     movhlps  xmm4,xmm1
     movhlps  xmm5,xmm2
     xorps    xmm3,xmm0
     xorps    xmm4,xmm1
     xorps    xmm5,xmm2
     andps    xmm3,xmm4
     andps    xmm3,xmm5
     movmskps eax,xmm3
     and      eax,11b
     cmp      eax,11b
     je       .in_area
   .chck_nx:
     pop      esi
     pop      ecx
     add      esi,12
     inc      ecx
     cmp      ecx,.triangles_count_var
     jnz      .chck
     jmp      .fin1
   .in_area:   ; whole tri in teslate area
     cmp      .chunkY,'chun' ; only one chunk tesselation ??
     jne      @f
     mov      eax,.tri_index
     add      eax,eax
     add      eax,[chunks_ptr]
     movzx    eax,word[eax]
     cmp      eax,.chu_no
     jne      .chck_nx
   @@:
     mov      eax,ecx
     cmp      .tiv,1
     jne      .nxxx       ; tiv -  checking ??
     movups   xmm1,[esi]  ; TIV - tri with at last one intersected edge and
                          ; with at last one inner vertex
     mov      ecx,3
   .back:
     movd     ebx,xmm1
     mov      edx,ebx
     shr      edx,3
     and      ebx,111b
     add      edx,[inner_vert_ptr]
     bt       dword [edx],ebx
     jnc      .nxxx
     psrldq   xmm1,4
     loop     .back
     jmp      .chck_nx
   .nxxx:
     cmp      [td_wp_flag],1  ; positive Z only check ???
     jne      .fwd
     mov      eax,.tri_index
     imul     eax,12
     xor      edi,edi
     add      eax,[triangles_normals_rotated_ptr]
     bt       dword[eax+8],31
     jnc      .chck_nx
   .fwd:
     ; search for correct ed index
     movd      xmm7,esi
     movups    xmm0,[esi]      ; edges
     movups    xmm1,[esi]
     shufps    xmm1,xmm1,11001001b
     movss     .endin,xmm1     ; end index
     mov       ecx,3
   .in1a:
     mov      .cnt1,ecx
   .nxv:
     movss    .endin,xmm1  ; end index
     movd     eax,xmm0
  ;  mov      eax,[esi]    ; esi - vert index
     shl      eax,2
     add      eax,.ptr     ; eax -  addr in pivot table
                           ; ptr to all edges with this vert
     mov      edi,[eax]
   .pi:                    ; search for edge
     mov      ebx,[edi+4]  ; ebx - ed index
     shl      ebx,3
     add      ebx,.edges_ptr
     mov      ecx,2
   .cm:
     mov      edx,[ebx]    ; ebx - vert index
     ;cmp      edx,[esi]   ; 1st index - first index is for sure
     ;je       .ok1
     cmp      edx,.endin   ; [esi+4]      ; 2cond
     je       .ok1
     ;cmp     edx,[esi+8]  ; 3dr
     ;je      .ok1
     add      ebx,4
     loop     .cm
     mov      ecx,[edi]    ; [edi] - vert index
     add      edi,8
     cmp      ecx,[edi]
     je       .pi          ; next pos in pivot table
     jmp      .fin1
     int3  ;sth wrong
   .ok1:
     ;pop      ecx
     mov      ecx,.cnt1
     mov      ebx,ecx
     psrldq   xmm0,4
     psrldq   xmm1,4
     dec      ebx
     shl      ebx,2
     lea      eax,.index3
     sub      eax,ebx
    ;dword[edi+4]    =   index   of edge
     mov      edx,.points_count_var
     add      edx,[edi+4]
     mov      [eax],edx
     loop     .in1a
     ;write new triangles - append to list
     mov      edi,.end_new_tri
     movd     esi,xmm7
     mov      eax,.points_count_var
     cmp      .tiv,1   ; tiv checking ?
     jne      .yes_inters
     mov      ecx,3
     movups   xmm4,.index1
   .bbbbb:
     movd     edx,xmm4
     sub      edx,eax
     mov      ebx,edx
     shr      edx,3
     and      ebx,111b
     add      edx,[edges_intersect_ptr]
     bt       dword[edx],ebx
     jc       .yes_inters
     psrldq   xmm4,4
     loop     .bbbbb
     jmp      .chck_nx
   .yes_inters:
     mov      edi,.end_new_tri
     movd     esi,xmm7
     ; mov      eax,.tri_index
     ; imul     eax,12
     ; add      eax,[triangles_normals_rotated]
     ; movups   xmm7,[eax]
     movlps   xmm4,[esi]
     movlps   xmm5,[esi+4]
     movlps   xmm6,[esi+8]
     ; xmm4 - xmm6   ->  indexes
     cld
     xchg     edi,esi
     movd     eax,xmm4
     stosd
     mov      eax,.index1
     stosd
     mov      eax,.index3
     stosd
     xchg     edi,esi
     mov      eax,.index1   ;        x4
     stosd                  ;       /  \
     mov      eax,.index2   ;    in1 -- in3
     stosd                  ;     / \  /  \
     mov      eax,.index3   ;    x5-in2 - x6
     stosd
     mov      eax,.index1
     stosd
     movd     eax,xmm5
     stosd
     mov      eax,.index2
     stosd
     mov      eax,.index3
     stosd
     mov      eax,.index2
     stosd
     movd     eax,xmm6
     stosd
     mov      .end_new_tri,edi
     add      .n_tri_cnt,3
     jmp      .chck_nx
   .fin1:
     ;reverse points_rotated to points_r
     xorps    xmm0,xmm0
     cvtdq2ps xmm3,[xxadd]
     movlhps  xmm3,xmm0
     mov      edi,.new_vert_ptr
     mov      ecx,.new_vcnt     ; vert number
   @@:
     movlps   xmm0,[edi]
     subps    xmm0,xmm3
     movlps   [edi],xmm0
     add      edi,12
     loop     @b
     mov      esi,matrix_scaled
     lea      edi,.mx
     call     reverse_mx_3x3
     mov      esi,.new_vert_ptr ; reverse transform tri area
     lea      ebx,.mx
     mov      edi,esi
     mov      ecx,.new_vcnt
     call     rotary
     mfree    .piv
     mfree    .ptr
     mov      esi,.new_tri
     mov      edi,.new_vert_ptr
     ;mov     [triangles_ptr],esi
     ;mov     [points_r_ptr],edi
     mov      ecx,.new_vcnt
     mov      ebx,.n_tri_cnt
     ;mov     [points_count_var],ecx
     add      ebx,[triangles_count_var]
   .end_aa:
     mov      esp,ebp
     pop      ebp
ret
;==============================================================
remove_unused_vertices:
; rem 'empty' indices from tri list
; and renew points r list
; in:
;    eax - triangles (faces) ptr
;    ebx - points (vertices) ptr
;    ecx - triangles (faces) count
;    edx - points (vertices) count
; out:
;    changed points_ptr(ebx) list
;    ecx - new vertices count

      push  ebp
      mov   ebp,esp
      sub   esp,40
     .triangles_ptr       equ [ebp-4]
     .points_ptr          equ [ebp-8]
     .triangles_count     equ [ebp-12]
     .points_count        equ dword[ebp-16]
     .triangles_pivot     equ dword[ebp-20]
     .triangles_pivot2    equ dword[ebp-24]
     .end_tri_pivot       equ dword[ebp-28]

      prompt   prompt_unused_vert

      mov      .triangles_ptr,eax
      mov      .points_ptr,ebx
      mov      .triangles_count,ecx
      mov      .points_count,edx
      ;2 ptrs   to continuous areas of mem -> so '.pivots'
      mov      ebx,.triangles_count
      imul     ebx,24
      push     ebx
      mov      eax,ebx
      add      eax,299
      malloc   eax
      mov      .triangles_pivot,eax
      mov      eax,.points_count
      imul     eax,12
      add      eax,399
      mov      ecx,ebx
      cmp      ecx,eax
      cmovb    ecx,eax
      malloc   ecx
      mov      .triangles_pivot2,eax   ; sec pivot - new vertices also
      pop      eax
      add      eax,.triangles_pivot
      add      eax,4
      mov      .end_tri_pivot,eax
      mov      esi,.triangles_ptr
      mov      edi,.triangles_pivot
      mov      eax,esi
      mov      ecx,.triangles_count
      cld
   @@:
      movsd
      stosd
      movsd
      stosd
      movsd
      stosd
      add      eax,12      ; eax - addres to  tri
      loop     @b
      mov      ecx,.triangles_count
      lea      ecx,[ecx*3]
      mov      esi,.triangles_pivot
      mov      edi,.triangles_pivot2
      call     sort_hybrid
      ; search for distinct
      ; for all tris with old distinct index - xchg with new
      mov      esi,.triangles_pivot
      xor      ecx,ecx     ; ecx - new index
      cld
   .nx_index:
      movd     xmm0,esi
   @@:
      cmp      esi,.end_tri_pivot
      jae      .en
      lodsd
      add      esi,4
      cmp      esi,.end_tri_pivot
      jae      .en
      cmp      eax,[esi]
      jne      .xchg_in    ; xchg indexes
      cmp      esi,.end_tri_pivot
      jne      @b      ; jne
   .nx_tri:
      cmp      esi,.end_tri_pivot
      jna      .nx_index
      jmp      .en
      ; I xchg EVERY index  to keep simplicity
   .xchg_in:
      mov      edx,eax     ; edx curr 'old' index
      push     esi
      movd     esi,xmm0
  .cure_old:
      mov      ebx,[esi]
      cmp      ebx,edx
      jne      .next2
      add      esi,4
      cmp      esi,.end_tri_pivot
      jnbe     .en
      lodsd
;      or       eax,eax
;      jz       .en
;      push     edx ecx
;      movlps   xmm1,[esp]
;      movaps   xmm2,xmm1
;      shufps   xmm1,xmm1,0
;      shufps   xmm2,xmm2,01010101b
;      movups   xmm3,[eax]
;      movaps   xmm4,xmm3
;      pcmpeqd  xmm3,xmm2
;      por      xmm3,xmm1
;      pand     xmm3,xmm4
;      movups   [eax],xmm3
;      add      esp,8

      or       eax,eax
      jz       .en
      cmp      [eax],edx
      jne      @f
      mov      [eax],ecx  ;ecx curr 'new'  index
   @@:
      cmp      [eax+4],edx
      jne      @f
      mov      [eax+4],ecx
   @@:
      cmp      [eax+8],edx
      jne      @f
      mov      [eax+8],ecx
   @@:            ; now I just putted new index - 'ecx' instedad old 'edx'
      jmp      .cure_old

   .next2:
      cld
      mov      esi,edx
      imul     esi,12
      add      esi,.points_ptr
      mov      edi,ecx
      imul     edi,12
      add      edi,.triangles_pivot2  ; .new_points
      movsd
      movsd
      movsd
      pop      esi
      inc      ecx
      jmp      .nx_tri
   .en:
      mov      [points_count_var],ecx
      mfree    .triangles_pivot
      mfree    .points_ptr
      push     .triangles_pivot2
      pop      [points_r_ptr]
      mov      ecx,[points_count_var]
      cls
      mov      esp,ebp
      pop      ebp

ret
